package com.louis.mail;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import org.apache.commons.mail.Email;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;

import com.louis.util.ArrayUtil;

/**
 * <p>
 * MailSenderImpl
 * </p>
 * 
 * @author
 * @DateTime Jul 29, 2011 3:08:54 PM
 * @version 1.0.0
 */
public class MailSenderImpl implements MailSender {

	private static final long	serialVersionUID	= 3332150842782673629L;
	protected final Logger		logger				= LogManager.getLogger(this.getClass());

	private String				encoding;
	private JavaMailSender		javaMailSender;
	private String				defaultFrom;
	private String				defaultTo;
	private String[]			defaultExceptionTo;
	private boolean				enabled				= false;

	public void send(Mail mail) {

	}

	public void send(Throwable throwable) {
		if (throwable != null) {
			doSend(defaultFrom, defaultExceptionTo, null, null, "Project exception message.", getThrowableMessage(throwable), false, encoding);
		} else {
			logger.warn("throwable is null.");
		}
	}

	protected void doSend(String from, String[] to, String[] cc, String[] bcc, String subject, String content, boolean html, String encoding, Attachment... attachments) {
		if (enabled) {
			boolean hasAttachment = ArrayUtil.hasArray(attachments);
			try {
				MimeMessage message = javaMailSender.createMimeMessage();
				MimeMessageHelper messageHelper = new MimeMessageHelper(message, hasAttachment, encoding);
				messageHelper.setFrom(from);
				messageHelper.setTo(to);
				messageHelper.setSubject(subject);
				messageHelper.setText(content, html);
				if (ArrayUtil.hasArray(cc)) {
					messageHelper.setCc(cc);
				}
				if (ArrayUtil.hasArray(bcc)) {
					messageHelper.setCc(bcc);
				}
				if (hasAttachment) {
					for (Attachment attachment: attachments) {
						messageHelper.addAttachment(attachment.getAttachmentName(), attachment.getInputStreamSource());
					}
				}
				javaMailSender.send(message);
			} catch (MessagingException e) {
				logger.error("Send mail failed", e);
			}
		} else {
			logger.warn("Send mail is not enabled");
		}
	}

	protected String getThrowableMessage(Throwable throwable) {
		StringBuffer content = new StringBuffer("Error Type:" + throwable.getClass().toString() + "<br/>Error Message:" + throwable.getMessage() + "<br/>Error Details:<br/>");

		for (StackTraceElement stackTrace: throwable.getStackTrace()) {
			content.append(stackTrace.toString());
			content.append("<br/>");
		}
		return content.toString();
	}

	public String getEncoding() {
		return encoding;
	}

	public void setEncoding(String encoding) {
		this.encoding = encoding;
	}

	public JavaMailSender getJavaMailSender() {
		return javaMailSender;
	}

	public void setJavaMailSender(JavaMailSender javaMailSender) {
		this.javaMailSender = javaMailSender;
	}

	public String getDefaultFrom() {
		return defaultFrom;
	}

	public void setDefaultFrom(String defaultFrom) {
		this.defaultFrom = defaultFrom;
	}

	public boolean isEnabled() {
		return enabled;
	}

	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}

	public static long getSerialVersionUID() {
		return serialVersionUID;
	}

	public Logger getLogger() {
		return logger;
	}

	public String[] getDefaultExceptionTo() {
		return defaultExceptionTo;
	}

	public void setDefaultExceptionTo(String[] defaultExceptionTo) {
		this.defaultExceptionTo = defaultExceptionTo;
	}

	/**
	 * @return the defaultTo
	 */
	public String getDefaultTo() {
		return this.defaultTo;
	}

	/**
	 * @param defaultTo
	 *            the defaultTo to set
	 */
	public void setDefaultTo(String defaultTo) {
		this.defaultTo = defaultTo;
	}

	/**
	 * @see com.louis.mail.MailSender#send(org.apache.commons.mail.Email)
	 */
	@Override
	public void send(Email email) {
		javaMailSender.send(email.getMimeMessage());
	}

}
